#include<iostream>
#include<string>
#include<fstream>
#include<thread>
#include<mutex>
#include<future>
using namespace std;

#define LOGAPP Logs::getInstance()

enum class log_level
{
    debug,
    info,
    warn,
    error
};

class Logs
{
    public:
        static Logs* getInstance();
        // 让编译器自动生成一个析构函数，不需要再定义
        ~Logs() = delete;

        void setUser_name(string user_name){this->user_name = user_name;}
        string getUser_name(){return user_name;}
        void setLog_name(string log_name){this->log_name = log_name;}
        string getLog_name(){return log_name;}
        void setLogs(string logs){this->logs = logs;}
        string getLogs(){return logs;}
        void setTime(int times){this->times = times;}
        int getTimes(){return times;}
        void setLog_level(log_level ll){this->ll = ll;}
        log_level getLog_level(){return ll;}

        void writeLog(const string& logs,const string& user_name,const string& log_name,int& times,log_level& ll);

    private:
        Logs() : user_name("user"), log_name("Logs.txt"), logs("no logs"), times(0), ll(log_level::debug){}
    private:
        string user_name;//日志操作人
        string log_name;//日志文件名称
        string logs;//日志内容
        int times;//日志写入时间
        log_level ll;//日志等级
        static Logs* m_log;
        static mutex m_mutex;
};
Logs* Logs::m_log = nullptr;
mutex Logs::m_mutex;
bool status = false;            //函数状态


Logs* Logs::getInstance()
{
    if(m_log == nullptr) {          
        lock_guard<mutex> lock(m_mutex);
        if(m_log == nullptr) {
            m_log = new Logs();
        }
    }
    return m_log;
}

void Logs::writeLog(const string& logs,const string& user_name,const string& log_name,int& times,log_level& ll)
{
    string tmp;
    if (ll == log_level::debug)
        tmp = "[DEBUG]       ";
    else if (ll == log_level::info)
        tmp = "[INFO]        ";
    else if (ll == log_level::warn)
        tmp = "[WARN]        ";
    else if (ll == log_level::error)
        tmp = "[ERROR]       ";
    else
    {
        return;
    }
    //上锁
    lock_guard<mutex> lock(m_mutex);
    ofstream ofs;
    
    LOGAPP->setLog_name(log_name);
    ofs.open(LOGAPP->getLog_name(),ios::app);

    LOGAPP->setUser_name(user_name);
    LOGAPP->setLogs(logs);
    LOGAPP->setTime(times);

    ofs << tmp << LOGAPP->getLogs() << " " << LOGAPP->getUser_name() << " " << LOGAPP->getTimes() << endl;

    ofs.close();
}

void write()
{
    string user_name = "wh";
    string log_name = "logss.txt";
    string logs = "hello world";
    log_level ll = log_level::debug;
    int times = 2023;
    LOGAPP->writeLog(logs,user_name,log_name,times,ll);
}

int main()
{
    //利用async替代线程创建实现异步
    auto write_future = async(launch::async, write);
    write_future.get();
    return 0;
}